/*
 * @Author: 0x9DEFA478
 * @Date: 2021-08-07 20:07:01
 * @LastEditTime: 2021-10-11 20:24:47
 * @LastEditors: 0x9DEFA478
 * @Description: 此文件实现了CMSIS-DAP 与 CDC的组合设备
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "usbd_class.h"
#include "usbd_class_if.h"
#include "usbd_ctlreq.h"
#include "usbd_ioreq.h"
#include "usbd_desc.h"

#define usbd_class_min(m1,m2)                                      (((m1)<(m2))?(m1):(m2))


extern unsigned int usbd_class_CtrlEndpointRecvData[];
extern unsigned int usbd_class_CtrlEndpointSendData[];

extern unsigned int usbd_class_CDC_OutData_Buffer_Even[];
extern unsigned int usbd_class_CDC_OutData_Buffer_Odd[];
extern unsigned int usbd_class_CDC_InData_Buffer[];


typedef struct _Class_FIFO{
  volatile int I;
  volatile int O;
  void* volatile* Buffers;
  int volatile* LengthArray;
  int Count;
}Class_FIFO;


//缓冲结构定义
typedef union{
  struct{
    volatile int IsOdd;
    unsigned int* Buffer_Even;
    unsigned int* Buffer_Odd;
    void (*Recv_Callback)(unsigned char*,int);
  }Recv;
  struct{
    volatile int IsBusy;
    unsigned int* Buffer;
    void (*TransmitDone_Callback)(void);
  }Transmit;
  struct{
    volatile int IsBusy;
    void* volatile TxData;
    volatile int TxDataLength;
    Class_FIFO FIFO;
  }Transmit_ISO;
}Class_Buffer;



typedef struct{
  void* pdev;

  Class_Buffer Buffers[vCDC_Buffer_Count];

  //请求处理方法
  int (*ReqExecute)(USBD_HandleTypeDef*,USBD_SetupReqTypedef*,unsigned char*,int*);

}Class_CDC;



//类结构体 保存各种参数
typedef struct{
  volatile int ConfigurationNum;

  //端点0数据缓存
  unsigned int* CtrlEndpointRecvData;
  unsigned int* CtrlEndpointSendData;

  //Setup包数据
  USBD_SetupReqTypedef SETUP;

  //端点0数据接收完成回调
  unsigned char (*volatile CtrlEndpointRecvCallback)(USBD_HandleTypeDef *pdev);

  int InterfaceAlternateSettings[vUSB_CountOfAllInterface];


  //CDC类
  Class_CDC CDC;
    
}USBD_CLASS;

USBD_CLASS usbd_class={
  .ConfigurationNum=0,
};


static unsigned char ConfigurationNon_SETUP(USBD_HandleTypeDef* pdev, USBD_SetupReqTypedef* req);

static unsigned char Configuration1_Init(USBD_HandleTypeDef *pdev);
static unsigned char Configuration1_DeInit(USBD_HandleTypeDef *pdev);
static unsigned char Configuration1_SETUP(USBD_HandleTypeDef* pdev, USBD_SetupReqTypedef* req);

static unsigned char Configuration2_Init(USBD_HandleTypeDef *pdev);
static unsigned char Configuration2_DeInit(USBD_HandleTypeDef *pdev);
static unsigned char Configuration2_SETUP(USBD_HandleTypeDef* pdev, USBD_SetupReqTypedef* req);

static USBD_EndpointTypeDef* OpenEndPoint(USBD_HandleTypeDef* pdev,uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps);
static USBD_EndpointTypeDef* CloseEndPoint(USBD_HandleTypeDef* pdev,uint8_t ep_addr);
//static int IsoINEndpointIncompleteExecute(USBD_HandleTypeDef* pdev,uint8_t epnum);


static uint8_t USBD_Class_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_Class_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_Class_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static uint8_t USBD_Class_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_Class_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_Class_EP0_RxReady(USBD_HandleTypeDef *pdev);
static uint8_t USBD_Class_EP0_TxReady(USBD_HandleTypeDef *pdev);
static uint8_t USBD_Class_SOF(USBD_HandleTypeDef *pdev);
static uint8_t USBD_Class_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_Class_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);

static uint8_t *USBD_Class_GetCfgDesc(uint16_t *length);
static uint8_t *USBD_Class_GetDeviceQualifierDesc(uint16_t *length);


USBD_ClassTypeDef USBD_Class_Driver={
  USBD_Class_Init,
  USBD_Class_DeInit,
  USBD_Class_Setup,
  USBD_Class_EP0_TxReady,
  USBD_Class_EP0_RxReady,
  USBD_Class_DataIn,
  USBD_Class_DataOut,
  USBD_Class_SOF,
  USBD_Class_IsoINIncomplete,
  USBD_Class_IsoOutIncomplete,
  USBD_Class_GetCfgDesc,
  USBD_Class_GetCfgDesc,
  USBD_Class_GetCfgDesc,
  USBD_Class_GetDeviceQualifierDesc,
};


#define vDescBuffer_Size 256U
__align(4) static unsigned char DescBuffer[vDescBuffer_Size];


#define vCfgDesc_Size (75U)
static const unsigned char CfgDesc[vCfgDesc_Size]={

  // **************** StandardConfigurationDescriptor ****************
  0x09,                                                            /* bLength: Configuation Descriptor size */
  vH_USB_DescType_Configuration,                                   /* bDescriptorType */
  cLittleTo2Bytes(vCfgDesc_Size),                                  /* wTotalLength */
  vUSB_CountOfAllInterface,                                        /* bNumInterfaces */
  0x01U,                                                           /* bConfigurationValue */
  USBD_IDX_PRODUCT_STR,                                            /* iConfiguration */
  0x80U,                                                           /* bmAttributes */
  50U,                                                             /* MaxPower */
  /* 09 */

  // **************** CDC ****************
  // **************** StandardInterfaceAssociationDescriptor ****************
  8U,                                                              /* bLength */
  vH_USB_DescType_InterfaceAssociation,                            /* bDescriptorType */
  vCDC_Control_Interface,                                          /* bFirstInterface */
  0x02U,                                                           /* bInterfaceCount */
  0x02U,                                                           /* bFunctionClass */
  0x02U,                                                           /* bFunctionSubClass */
  0x01U,                                                           /* bInterfaceProtocol: 该IAD下的InterfaceProtocol */
  USBD_IDX_PRODUCT_STR,                                            /* iFunction */
  /* 17 */

  // **************** InterfaceDescriptor ****************    接口类型: CDC控制接口
  9U,                                                              /* bLength */
  vH_USB_DescType_Interface,                                       /* bDescriptorType */
  vCDC_Control_Interface,                                          /* bInterfaceNumber */
  0x00U,                                                           /* bAlternateSetting */
  0x01U,                                                           /* bNumEndpoints: 该接口使用的端点数量 */
  0x02U,                                                           /* bInterfaceClass */
  0x02U,                                                           /* bInterfaceSubClass */
  0x01U,                                                           /* bInterfaceProtocol */
  0x68U,                                                           /* iInterface */
  /* 26 */

  // **************** HeaderFunctionalDescriptor ****************
	5U,                                                              /* bLength: Endpoint Descriptor size */
	vH_USB_DescType_ClassSpecificInterface,                          /* bDescriptorType */
	0x00U,                                                           /* bDescriptorSubtype: Header Func Desc */
	cLittleTo2Bytes(0x0110U),                                        /* bcdCDC: spec release number */
	/* 31 */

  // **************** CallManagementFunctionalDescriptor ****************
	5U,                                                              /* bFunctionLength */
	vH_USB_DescType_ClassSpecificInterface,                          /* bDescriptorType: CS_INTERFACE */
	0x01U,                                                           /* bDescriptorSubtype: Call Management Func Desc */
	0x00U,                                                           /* bmCapabilities: D0+D1 */
	vCDC_Data_Interface,                                             /* bDataInterface */
	/* 36 */

  // **************** ACMFunctionalDescriptor ****************
	4U,                                                              /* bFunctionLength */
	vH_USB_DescType_ClassSpecificInterface,                          /* bDescriptorType: CS_INTERFACE */
	0x02U,                                                           /* bDescriptorSubtype: Abstract Control Management desc */
	0x02U,                                                           /* bmCapabilities */
	/* 40 */

  // **************** UnionFunctionalDescriptor ****************
	5U,                                                              /* bFunctionLength */
	vH_USB_DescType_ClassSpecificInterface,                          /* bDescriptorType: CS_INTERFACE */
	0x06U,                                                           /* bDescriptorSubtype */
	vCDC_Control_Interface,                                          /* bControlInterface */
	vCDC_Data_Interface,                                             /* bSubordinateInterface0 */
	/* 45 */
	
  // **************** 端点描述符 ****************
	7U,                                                              /* bLength */
	vH_USB_DescType_Endpoint,                                        /* bDescriptorType */
	vH_USB_DescType_ClassSpecificEndpoint,                           /* bEndpointAddress */
	0x03U,                                                           /* bmAttributes: 0x03:Interrupt */
	cLittleTo2Bytes(vCDC_Control_InEndPointSize),                    /* wMaxPacketSize */
	0x10U,                                                           /* bInterval */
	/* 52 */

  // **************** StandardInterfaceDescriptor ****************    接口类型: CDC数据类
	9U,                                                              /* bLength */
	vH_USB_DescType_Interface,                                       /* bDescriptorType */
	vCDC_Data_Interface,                                             /* bInterfaceNumber */
	0x00U,                                                           /* bAlternateSetting */
	0x02U,                                                           /* bNumEndpoints */
	0x0AU,                                                           /* bInterfaceClass */
	0x00U,                                                           /* bInterfaceSubClass */
	0x00U,                                                           /* bInterfaceProtocol */
	0x68U,                                                           /* iInterface: */
	/* 61 */

  // **************** 端点描述符 ****************
	7U,                                                              /* bLength */
	vH_USB_DescType_Endpoint,                                        /* bDescriptorType */
	vCDC_Data_OutEndPoint,                                           /* bEndpointAddress */
	0x02U,                                                           /* bmAttributes: 0x02:Bulk */
	cLittleTo2Bytes(vCDC_Data_OutEndPointSize),                     /* wMaxPacketSize */
	0x00U,                                                           /* bInterval */
	/* 68 */

  // **************** 端点描述符 ****************
	7U,                                                              /* bLength */
	vH_USB_DescType_Endpoint,                                        /* bDescriptorType */
	vCDC_Data_InEndPoint,                                            /* bEndpointAddress */
	0x02U,                                                           /* bmAttributes: 0x02:Bulk */
	cLittleTo2Bytes(vCDC_Data_InEndPointSize),                       /* wMaxPacketSize */
	0x00U,                                                           /* bInterval */
	/* 75 */
  

};


static const unsigned char DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]={
  USB_LEN_DEV_QUALIFIER_DESC,                                      /* bLength */
  USB_DESC_TYPE_DEVICE_QUALIFIER,                                  /* bDescriptorType */
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
  cLittleTo2Bytes(0x0201U),                                        /* bcdUSB */     /* changed to USB version 2.01 in order to support BOS Desc */
#else
  cLittleTo2Bytes(0x0200U),                                        /* bcdUSB */
#endif
  0xEF,                                                            /* bDeviceClass */
  0x02,                                                            /* bDeviceSubClass */
  0x01,                                                            /* bDeviceProtocol */
  0x40,                                                            /* bMaxPacketSize0 */
  0x01,                                                            /* bNumConfigurations */
  0x00,                                                            /* bReserved */
};

#if vDescBuffer_Size<vCfgDesc_Size
#error "DescBuffer过小"
#endif
#if vDescBuffer_Size<USB_LEN_DEV_QUALIFIER_DESC
#error "DescBuffer过小"
#endif
#if vDescBuffer_Size<vHID_ReportDescriptor_Size
#error "DescBuffer过小"
#endif



//============================================================================================================================================
//
// USBD_ClassTypeDef需要的方法
//
//============================================================================================================================================

/**
 * @brief 初始化类配置
 * @param pdev USBD句柄
 * @param cfgidx 配置编号
 * @return status
 */
static uint8_t USBD_Class_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx){

  switch(cfgidx){
    case 1:
      return Configuration1_Init(pdev);
    case 2:
      return Configuration2_Init(pdev);
    default:
      break;
  }

  return (uint8_t)USBD_FAIL;
}

static uint8_t USBD_Class_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx){
  switch(cfgidx){
    case 1:
      return Configuration1_DeInit(pdev);
    case 2:
      return Configuration2_DeInit(pdev);
    default:
      break;
  }
  
  return (uint8_t)USBD_FAIL;
}

//接收到SETUP包回调
static uint8_t USBD_Class_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req){
  USBD_StatusTypeDef ret;

  switch(usbd_class.ConfigurationNum){
    case 1:
      return Configuration1_SETUP(pdev,req);
    case 2:
      return Configuration2_SETUP(pdev,req);
    default:
      return ConfigurationNon_SETUP(pdev,req);
  }

  USBD_CtlError(pdev,req);
  ret=USBD_FAIL;
  return (uint8_t)ret;
}

//非零端点数据发送完成回调
static uint8_t USBD_Class_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum){

  if(usbd_class.ConfigurationNum==1){
    switch(epnum&0x0FU){
      case vCDC_Data_InEndPoint&0x0FU:

        usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.IsBusy=0;
        usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.TransmitDone_Callback();

        break;
      default:
        break;
    }
  }

  return (uint8_t)USBD_OK;
}

//非零端点数据接收完成回调
static uint8_t USBD_Class_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum){
  unsigned int RxLength;

  union{
    Class_CDC* CDC;
  }this_class;

  Class_Buffer* classBuffer;

  if(usbd_class.ConfigurationNum==1){

    RxLength=USBD_LL_GetRxDataSize(pdev,epnum);

    switch(epnum&0x0FU){
      case vCDC_Data_InEndPoint&0x0FU:
        this_class.CDC=&usbd_class.CDC;
        classBuffer=&this_class.CDC->Buffers[vCDC_Data_OutEndPoint_UseBuffer];

        if(classBuffer->Recv.IsOdd==0){
          USBD_LL_PrepareReceive(pdev,epnum,(unsigned char*)classBuffer->Recv.Buffer_Odd,vCDC_Data_OutEndPointSize);
          classBuffer->Recv.Recv_Callback((unsigned char*)classBuffer->Recv.Buffer_Even,RxLength);
          classBuffer->Recv.IsOdd=-1;
        }else{
          USBD_LL_PrepareReceive(pdev,epnum,(unsigned char*)classBuffer->Recv.Buffer_Even,vCDC_Data_OutEndPointSize);
          classBuffer->Recv.Recv_Callback((unsigned char*)classBuffer->Recv.Buffer_Odd,RxLength);
          classBuffer->Recv.IsOdd=0;
        }
        
        break;

      
      default:
        break;
    }
  }

  return (uint8_t)USBD_OK;
}

//端点0数据接收完成回调
static uint8_t USBD_Class_EP0_RxReady(USBD_HandleTypeDef *pdev){
  if(usbd_class.ConfigurationNum==1){
    if(usbd_class.CtrlEndpointRecvCallback!=NULL){
      usbd_class.CtrlEndpointRecvCallback(pdev);
    }
  }
  return (uint8_t)USBD_OK;
}

//端点0数据发送完成回调
static uint8_t USBD_Class_EP0_TxReady(USBD_HandleTypeDef *pdev){
  if(usbd_class.ConfigurationNum==1){
  }
  return (uint8_t)USBD_OK;
}

//SOF中断回调
static uint8_t USBD_Class_SOF(USBD_HandleTypeDef *pdev){
  Class_Buffer* doubleBuffer;
  int I;
  int O;
  void* Buffer;
  int Size;

  if(usbd_class.ConfigurationNum==1){

  }
  return (uint8_t)USBD_OK;
}

//ISO发送未完成回调(在一帧结束后 数据仍未传输完成)
static uint8_t USBD_Class_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum){
  if(usbd_class.ConfigurationNum==1){
  }
  return (uint8_t)USBD_OK;
}

//ISO接收未完成回调(在一帧结束后 数据仍未传输完成)
static uint8_t USBD_Class_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum){
  if(usbd_class.ConfigurationNum==1){
  }
  return (uint8_t)USBD_OK;
}


static uint8_t *USBD_Class_GetCfgDesc(uint16_t *length){
  int i;
  int Length;
  const unsigned char* src;

  src=CfgDesc;
  Length=vCfgDesc_Size;

  for(i=0;i<Length;i++){
    DescBuffer[i]=src[i];
  }
  *length=Length;

  return DescBuffer;
}

static uint8_t *USBD_Class_GetDeviceQualifierDesc(uint16_t *length){
  int i;

  for(i=0;i<USB_LEN_DEV_QUALIFIER_DESC;i++){
    DescBuffer[i]=DeviceQualifierDesc[i];
  }
  
  *length=USB_LEN_DEV_QUALIFIER_DESC;
  return DescBuffer;
}









//============================================================================================================================================
//
// 提供的外部方法
//
//============================================================================================================================================

static int CDC_ReqExecute(USBD_HandleTypeDef* pdev,USBD_SetupReqTypedef* req,unsigned char* data,int* Length);


/**
 * @brief 类预先初始化
 * @return 无
 */
void usbd_class_Init_m(){
  usbd_class.CDC.ReqExecute=CDC_ReqExecute;
}

/**
 * @brief 获取配置号
 * @return 配置号 如果为0代表未设置配置
 */
int usbd_class_GetConfigurationNum_m(){
  return usbd_class.ConfigurationNum;
}

/**
 * @brief 发送数据 
 * @param pdev usb句柄
 * @param Data 要发送的数据 此地址要4字节对齐
 * @param Length 发送的数据长度
 * @return 0:成功 其他:失败
 */
int usbd_class_CDC_Send_m(void* pdev,unsigned char* Data,int Length){
  int length;
  unsigned char* dst;

  switch(usbd_class.ConfigurationNum){
    case 1:
      if(usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.IsBusy==0){
        usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.IsBusy=-1;

        length=usbd_class_min(Length,vCDC_Data_InEndPointSize);
        Length=length;
        dst=(unsigned char*)usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.Buffer;

        while(length>=8){
          length-=8;
          
          dst[0]=Data[0];
          dst[1]=Data[1];
          dst[2]=Data[2];
          dst[3]=Data[3];
          dst[4]=Data[4];
          dst[5]=Data[5];
          dst[6]=Data[6];
          dst[7]=Data[7];

          Data=&Data[8];
          dst=&dst[8];
        }
        while(length>0){
          length--;

          dst[0]=Data[0];

          Data=&Data[1];
          dst=&dst[1];
        }

        USBD_LL_Transmit(pdev,vCDC_Data_InEndPoint,(unsigned char*)usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.Buffer,Length);
        return 0;
      }
      return -1;
    case 2:
      break;
    default:
      break;
  }

  return -2;
}

/**
 * @brief 检查发送是否忙碌
 * @param pdev usb句柄
 * @return 0:空闲 其他:忙碌
 */
int usbd_class_CDC_IsBusy_m(void* pdev){
  switch(usbd_class.ConfigurationNum){
    case 1:
      if(usbd_class.CDC.Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.IsBusy==0){
        return 0;
      }
      return -1;
    case 2:
      break;
    default:
      break;
  }

  return -2;
}




//============================================================================================================================================
//
// 用户方法
//
//============================================================================================================================================

//CDC类控制节点接收回调
static unsigned char CDC_CtrlEndpointRecvCallback(USBD_HandleTypeDef *pdev){
  USBD_SetupReqTypedef* req;
  int err;
  int Length;

  err=0;
  
  err=usbd_class.CDC.ReqExecute(pdev,&usbd_class.SETUP,(unsigned char*)usbd_class.CtrlEndpointRecvData,&Length);
  
  if(err!=0){
    USBD_CtlError(pdev,req);
  }

  return (unsigned char)USBD_OK;
}

/**
 * @brief CDC请求解析
 * @param pdev usb句柄
 * @param req 请求
 * @return noEdit
 */
static unsigned char CDC_SetupReqDecode(USBD_HandleTypeDef* pdev,USBD_SetupReqTypedef* req){
  int err;
  int Length;

  err=0;

  if(req->wLength==0){
    err=usbd_class.CDC.ReqExecute(pdev,req,NULL,&Length);
  }else{
    if((req->bmRequest&0x80)==0U){
      //Set
      usbd_class.CtrlEndpointRecvCallback=CDC_CtrlEndpointRecvCallback;
      usbd_class.SETUP=*req;
      USBD_CtlPrepareRx(pdev,(unsigned char*)usbd_class.CtrlEndpointRecvData,req->wLength);
    }else{
      //Get
      err=usbd_class.CDC.ReqExecute(pdev,req,(unsigned char*)usbd_class.CtrlEndpointSendData,&Length);
      if(err==0){
        USBD_CtlSendData(pdev,(unsigned char*)usbd_class.CtrlEndpointSendData,Length);
      }
    }
  }

  if(err!=0){
    USBD_CtlError(pdev,req);
  }

  return (unsigned char)USBD_OK;
}








//============================================================================================================================================
//
// 配置初始化与SETUP相关处理
//
//============================================================================================================================================

/**
 * @brief 配置 non Setup包处理
 * @param pdev usb句柄
 * @param req 请求
 * @return status
 */
static unsigned char ConfigurationNon_SETUP(USBD_HandleTypeDef* pdev,USBD_SetupReqTypedef* req){

  switch(req->bmRequest&USB_REQ_TYPE_MASK){

    case USB_REQ_TYPE_CLASS:
      //类请求

      switch(req->bmRequest&USB_REQ_RECIPIENT_MASK){
        
        case USB_REQ_RECIPIENT_DEVICE:
          //器件请求
          break;

        case USB_REQ_RECIPIENT_INTERFACE:
          //接口请求
          break;

        case USB_REQ_RECIPIENT_ENDPOINT:
          //端点请求
          break;

        default:
          break;
      }
      break;

    case USB_REQ_TYPE_VENDOR:
      //厂商请求

      switch(req->bmRequest&USB_REQ_RECIPIENT_MASK){
        
        case USB_REQ_RECIPIENT_DEVICE:
          //器件请求

#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
          if(req->bRequest==USB_MS_VendorCode){
            switch(req->wIndex){
              case 0x0007U:
                if((req->bmRequest&0x80U)==0x80U){
                  ucp=USBD_Class_MS_OS_20_DescriptorSet(pdev->dev_speed,&Length);
                  Length=MIN(Length,req->wLength);
                  if(Length!=0){
                    USBD_CtlSendData(pdev,ucp,Length);
                  }
                  return USBD_OK;
                }
                break;
              case 0x0008U:
                break;
              default:
                break;
            }
          }
#endif

          break;

        case USB_REQ_RECIPIENT_INTERFACE:
          //接口请求
          break;

        case USB_REQ_RECIPIENT_ENDPOINT:
          //端点请求
          break;

        default:
          break;
      }
      break;

    case USB_REQ_TYPE_STANDARD:
      //标准请求

      switch(req->bmRequest&USB_REQ_RECIPIENT_MASK){

        case USB_REQ_RECIPIENT_DEVICE:
          //器件请求
          break;

        case USB_REQ_RECIPIENT_INTERFACE:
          //接口请求
          break;

        case USB_REQ_RECIPIENT_ENDPOINT:
          //端点请求
          break;

        default:
          break;
      }
      break;

    default:
      break;
  }

  //如果没有做出响应 必须调用这个
  USBD_CtlError(pdev,req);
  return (unsigned char)USBD_OK;
}

/**
 * @brief 配置1初始化
 * @param pdev usb句柄
 * @return status
 */
static unsigned char Configuration1_Init(USBD_HandleTypeDef* pdev){
  Class_CDC* CDC;
  USBD_EndpointTypeDef* endpoint;
  int i;

  //类全局初始化
  usbd_class.ConfigurationNum=1;
  usbd_class.CtrlEndpointRecvData=usbd_class_CtrlEndpointRecvData;
  usbd_class.CtrlEndpointSendData=usbd_class_CtrlEndpointSendData;
  usbd_class.CtrlEndpointRecvCallback=NULL;
  for(i=0;i<vUSB_CountOfAllInterface;i++){
    usbd_class.InterfaceAlternateSettings[i]=0;
  }
  

  //各个类初始化
  //音频类

  CDC=&usbd_class.CDC;
  CDC->pdev=pdev;

  
  CDC->Buffers[vCDC_Data_OutEndPoint_UseBuffer].Recv.IsOdd=0;
  CDC->Buffers[vCDC_Data_OutEndPoint_UseBuffer].Recv.Buffer_Even=usbd_class_CDC_OutData_Buffer_Even;
  CDC->Buffers[vCDC_Data_OutEndPoint_UseBuffer].Recv.Buffer_Odd=usbd_class_CDC_OutData_Buffer_Odd;
  CDC->Buffers[vCDC_Data_OutEndPoint_UseBuffer].Recv.Recv_Callback=usbd_class_CDC_RecvCallback;
  CDC->Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.IsBusy=0;
  CDC->Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.Buffer=usbd_class_CDC_InData_Buffer;
  CDC->Buffers[vCDC_Data_InEndPoint_UseBuffer].Transmit.TransmitDone_Callback=usbd_class_CDC_SendDoneCallback;

  
  

  //端点初始化
  endpoint=OpenEndPoint(pdev,vCDC_Data_OutEndPoint,USBD_EP_TYPE_BULK,vCDC_Data_OutEndPointSize);
  endpoint->bInterval=0;

  endpoint=OpenEndPoint(pdev,vCDC_Data_InEndPoint,USBD_EP_TYPE_BULK,vCDC_Data_InEndPointSize);
  endpoint->bInterval=0;

  endpoint=OpenEndPoint(pdev,vCDC_Control_InEndPoint,USBD_EP_TYPE_BULK,vCDC_Control_InEndPointSize);
  endpoint->bInterval=0;

  //Out端点预接收
  USBD_LL_PrepareReceive(pdev
  ,vCDC_Data_OutEndPoint
  ,(unsigned char*)CDC->Buffers[vCDC_Data_OutEndPoint_UseBuffer].Recv.Buffer_Even
  ,vCDC_Data_OutEndPointSize);


  usbd_class_ConnectCallback(1);

  return (unsigned char)USBD_OK;
} 

/**
 * @brief 配置1反初始化
 * @param pdev usb句柄
 * @return status
 */
static unsigned char Configuration1_DeInit(USBD_HandleTypeDef* pdev){

  CloseEndPoint(pdev,vCDC_Data_OutEndPoint);

  CloseEndPoint(pdev,vCDC_Data_InEndPoint);

  CloseEndPoint(pdev,vCDC_Control_InEndPoint);

  usbd_class.ConfigurationNum=0;
  usbd_class_DisConnectCallback(1);

  return (unsigned char)USBD_OK;
}

/**
 * @brief 配置1 Setup包处理
 * @param pdev usb句柄
 * @param req 请求
 * @return status
 */
static unsigned char Configuration1_SETUP(USBD_HandleTypeDef* pdev,USBD_SetupReqTypedef* req){

  switch(req->bmRequest&USB_REQ_TYPE_MASK){

    case USB_REQ_TYPE_CLASS:
      //类请求

      switch(req->bmRequest&USB_REQ_RECIPIENT_MASK){
        
        case USB_REQ_RECIPIENT_DEVICE:
          //器件请求
          break;

        case USB_REQ_RECIPIENT_INTERFACE:
          //接口请求

          switch(req->wIndex&0x0FU){
            case vCDC_Control_Interface:
            case vCDC_Data_Interface:
              return CDC_SetupReqDecode(pdev,req);
            default:
              break;
          }

          break;

        case USB_REQ_RECIPIENT_ENDPOINT:
          //端点请求
          break;

        default:
          break;
      }
      break;

    case USB_REQ_TYPE_VENDOR:
      //厂商请求

      switch(req->bmRequest&USB_REQ_RECIPIENT_MASK){
        
        case USB_REQ_RECIPIENT_DEVICE:
          //器件请求

#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
          if(req->bRequest==USB_MS_VendorCode){
            switch(req->wIndex){
              case 0x0007U:
                if((req->bmRequest&0x80U)==0x80U){
                  ucp=USBD_Class_MS_OS_20_DescriptorSet(pdev->dev_speed,&Length);
                  Length=MIN(Length,req->wLength);
                  if(Length!=0){
                    USBD_CtlSendData(pdev,ucp,Length);
                  }
                  return (unsigned char)USBD_OK;
                }
                break;
              case 0x0008U:
                break;
              default:
                break;
            }
          }
#endif

          break;

        case USB_REQ_RECIPIENT_INTERFACE:
          //接口请求
          break;

        case USB_REQ_RECIPIENT_ENDPOINT:
          //端点请求
          break;

        default:
          break;
      }
      break;

    case USB_REQ_TYPE_STANDARD:
      //标准请求

      switch(req->bmRequest&USB_REQ_RECIPIENT_MASK){

        case USB_REQ_RECIPIENT_DEVICE:
          //器件请求
          break;

        case USB_REQ_RECIPIENT_INTERFACE:
          //接口请求

          switch(req->bRequest){
            case USB_REQ_SET_INTERFACE:

              if((req->bmRequest&0x80U)==0U){
                //Set请求
                usbd_class.InterfaceAlternateSettings[req->wIndex&0x00FF]=req->wValue;
                return (unsigned char)USBD_OK;
              }else{
                //Get请求
                break;
              }

              break;
            case USB_REQ_GET_INTERFACE:

              if((req->bmRequest&0x80U)==0U){
                //Set请求
                break;
              }else{
                //Get请求
                usbd_class.CtrlEndpointSendData[0]=usbd_class.InterfaceAlternateSettings[req->wIndex&0x00FF];
                USBD_CtlSendData(pdev,(unsigned char*)usbd_class.CtrlEndpointSendData,req->wLength);
                return (unsigned char)USBD_OK;
              }

              break;
            default:
              break;
          }

          break;

        case USB_REQ_RECIPIENT_ENDPOINT:
          //端点请求
          break;

        default:
          break;
      }
      break;

    default:
      break;
  }

  //如果没有做出响应 必须调用这个
  USBD_CtlError(pdev,req);
  return (unsigned char)USBD_OK;
}



/**
 * @brief 配置2初始化
 * @param pdev usb句柄
 * @return status
 */
static unsigned char Configuration2_Init(USBD_HandleTypeDef* pdev){
  return (unsigned char)USBD_FAIL;
}

/**
 * @brief 配置2反初始化
 * @param pdev usb句柄
 * @return status
 */
static unsigned char Configuration2_DeInit(USBD_HandleTypeDef* pdev){
  return (unsigned char)USBD_FAIL;
}

/**
 * @brief 配置2 Setup包处理
 * @param pdev usb句柄
 * @param req 请求
 * @return status
 */
static unsigned char Configuration2_SETUP(USBD_HandleTypeDef* pdev, USBD_SetupReqTypedef* req){
  USBD_CtlError(pdev,req);
  return (unsigned char)USBD_FAIL;
}




//============================================================================================================================================
//
// 端点操作封装
//
//============================================================================================================================================

static USBD_EndpointTypeDef* OpenEndPoint(USBD_HandleTypeDef* pdev,uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps){
  USBD_EndpointTypeDef* r;

  USBD_LL_OpenEP(pdev,ep_addr,ep_type,ep_mps);
  if((ep_addr&0x80U)==0x80U){
    r=&pdev->ep_in[ep_addr & 0xFU];
  }else{
    r=&pdev->ep_out[ep_addr & 0xFU];
  }
  r->is_used=1U;
  return r;
}

static USBD_EndpointTypeDef* CloseEndPoint(USBD_HandleTypeDef* pdev,uint8_t ep_addr){
  USBD_EndpointTypeDef* r;

  USBD_LL_CloseEP(pdev,ep_addr);
  if((ep_addr&0x80U)==0x80U){
    r=&pdev->ep_in[ep_addr & 0xFU];
  }else{
    r=&pdev->ep_out[ep_addr & 0xFU];
  }
  r->is_used=0U;
  r->bInterval=0U;
  return r;
}

// F103的USB没有同步传输未完成中断 故没有处理方法
// static int IsoINEndpointIncompleteExecute(USBD_HandleTypeDef* pdev,uint8_t epnum){
//   unsigned int USBx_BASE;

//   USBx_BASE=(unsigned int)((PCD_HandleTypeDef*)pdev->pData)->Instance;

//   if((USBx_INEP(epnum&0x0FU)->DIEPCTL&USB_OTG_DIEPCTL_EPENA)!=0U){
//     USBx_INEP(epnum&0x0FU)->DIEPCTL|=USB_OTG_DIEPCTL_SNAK;
//     USBx_INEP(epnum&0x0FU)->DIEPCTL|=USB_OTG_DIEPCTL_EPDIS;

//     return -1;
//   }

//   return 0;
// }




//============================================================================================================================================
//
// 类处理方法
//
//============================================================================================================================================

static int CDC_ReqExecute(USBD_HandleTypeDef* pdev,USBD_SetupReqTypedef* req,unsigned char* data,int* Length){

  usbd_class_CDC_Ctrl_Callback(req,data,req->wLength);

  return 0;
}


